/**
 * 穿跨越桁架外部荷载计算算法模块
 * 提供桥梁跨越大腿结构设计的各类外部荷载计算功能
 * 包括管道自重、介质重量、风荷载、雪荷载等多种荷载类型
 * 基于相关设计规范（GB50009等）进行荷载计算
 */

/**
 * 穿跨越桁架外部荷载计算算法类
 * 实现桥梁跨越大腿结构所受各类外部荷载的计算方法
 * 考虑管道特性、环境因素和使用条件的综合影响
 */
export class CrossingTrussExternalLoadAlgorithms {
  /**
   * 管道自重荷载计算
   * 根据管道的外径、壁厚和材料密度，计算单位长度管道的自重荷载
   * 基于管道圆环截面积与材料密度的乘积计算重量
   * 
   * @param {number} diameter 管道外径 (m)
   * @param {number} thickness 管道壁厚 (m)
   * @param {number} density 钢材密度 (kg/m³)，默认为7850 (Q235钢材)
   * @returns {number} 管道单位长度自重荷载 (N/m)
   */
  static pipeWeightLoad(
    diameter: number,
    thickness: number,
    density: number,
  ): number {
    // 计算管道外半径
    const outerRadius = diameter / 2;
    
    // 计算管道内半径
    const innerRadius = outerRadius - thickness;
    
    // 计算管道圆环截面积：π*(R²-r²)
    const crossSectionArea = Math.PI * (Math.pow(outerRadius, 2) - Math.pow(innerRadius, 2));
    
    // 计算单位长度重量：截面积 * 密度
    const weightPerMeter = crossSectionArea * density;
    
    // 计算单位长度荷载：重量 * 重力加速度 (转换为N/m)
    const load = weightPerMeter * 9.81;
    
    // 保留两位小数返回
    return parseFloat(load.toFixed(2));
  }

  /**
   * 介质重量荷载计算
   * 根据管道内直径和介质密度，计算单位长度管道内介质的重量荷载
   * 基于管道圆形截面积与介质密度的乘积计算重量
   * 
   * @param {number} diameter 管道内径 (m)
   * @param {number} mediumDensity 介质密度 (kg/m³)
   * @returns {number} 介质单位长度重量荷载 (N/m)
   */
  static mediumWeightLoad(
    diameter: number,
    mediumDensity: number
  ): number {
    // 计算管道内半径
    const innerRadius = diameter / 2;
    
    // 计算管道圆形截面积：π*r²
    const crossSectionArea = Math.PI * Math.pow(innerRadius, 2);
    
    // 计算单位长度介质重量：截面积 * 介质密度
    const weightPerMeter = crossSectionArea * mediumDensity;
    
    // 计算单位长度介质荷载：重量 * 重力加速度 (转换为N/m)
    const load = weightPerMeter * 9.81;
    
    // 保留两位小数返回
    return parseFloat(load.toFixed(2));
  }

  /**
   * 保温层重量荷载计算
   * 根据保温层的内外直径和密度，计算单位长度保温层的重量荷载
   * 基于保温层圆环截面积与材料密度的乘积计算重量
   * 
   * @param {number} outerDiameter 保温层外径 (m)
   * @param {number} innerDiameter 保温层内径(管道外径) (m)
   * @param {number} insulationDensity 保温层密度 (kg/m³)
   * @returns {number} 保温层单位长度重量荷载 (N/m)
   */
  static insulationWeightLoad(
    outerDiameter: number,
    innerDiameter: number,
    insulationDensity: number
  ): number {
    // 计算保温层外半径
    const outerRadius = outerDiameter / 2;
    
    // 计算保温层内半径
    const innerRadius = innerDiameter / 2;
    
    // 计算保温层圆环截面积：π*(R²-r²)
    const crossSectionArea = Math.PI * (Math.pow(outerRadius, 2) - Math.pow(innerRadius, 2));
    
    // 计算单位长度保温层重量：截面积 * 保温层密度
    const weightPerMeter = crossSectionArea * insulationDensity;
    
    // 计算单位长度保温层荷载：重量 * 重力加速度 (转换为N/m)
    const load = weightPerMeter * 9.81;
    
    // 保留两位小数返回
    return parseFloat(load.toFixed(2));
  }

  /**
   * 附属设备重量荷载计算
   * 将附属设备总重量均匀分布在跨度长度上，计算单位长度的荷载
   * 考虑设备重量在整个跨度内的平均分布
   * 
   * @param {number} equipmentWeight 附属设备总重量 (kg)
   * @param {number} spanLength 跨度长度 (m)
   * @returns {number} 附属设备单位长度重量荷载 (N/m)
   */
  static equipmentWeightLoad(
    equipmentWeight: number,
    spanLength: number,
  ): number {
    // 防止除零错误
    if (spanLength <= 0) {
      return 0;
    }
    
    // 计算单位长度设备荷载：总重量 * 重力加速度 / 跨度长度 (转换为N/m)
    const load = (equipmentWeight * 9.81) / spanLength;
    
    // 保留两位小数返回
    return parseFloat(load.toFixed(2));
  }

  /**
   * 风荷载计算
   * 根据设计规范GB50009，计算结构所受的风荷载标准值
   * 考虑风振系数、体型系数、高度变化系数和基本风压的综合影响
   * 
   * @param {number} windPressure 基本风压 (kN/m²)，符合GB50009取值
   * @param {number} windShapeFactor 风荷载体型系数，跨越设计规范27页
   * @param {number} windHeightFactor 风压高度变化系数，根据GB50009确定
   * @param {number} windVibrationFactor 高度z处的风振系数，跨越设计规范25页
   * @returns {number} 风荷载标准值 (N/m)
   */
  static windLoad(
    windPressure: number,
    windShapeFactor: number,
    windHeightFactor: number,
    windVibrationFactor: number,
  ): number {
    // 风荷载标准值计算公式：βz * μs * μz * ω0
    // βz - 风振系数
    // μs - 风荷载体型系数
    // μz - 风压高度变化系数
    // ω0 - 基本风压
    const load = windVibrationFactor * windShapeFactor * windHeightFactor * windPressure * 1000; // 转换为N/m
    
    // 保留两位小数返回
    return parseFloat(load.toFixed(2));
  }

  /**
   * 雪荷载计算
   * 根据设计规范GB50009，计算结构所受的雪荷载标准值
   * 考虑积雪分布系数、基本雪压、镂空折减系数和投影面积等因素
   * 
   * @param {number} snowDistributionCoefficient 积雪分布系数，取1.0
   * @param {number} snowPressure 基本雪压 (kN/m²)，按照GB50009附录A.2取值
   * @param {number} openingReductionCoefficient 镂空折减系数，当管道投影面积小于等于0.8时取0.9，走道板位于两管道之间时取1
   * @param {number} projectionAreaOfSectionsPipesWalkways Ab型钢、管道及走道板在计算桥面的投影面积（m²）
   * @param {number} totalContourAreaOfCalculationDeck A1计算桥面轮廓总面积 (m²)
   * @returns {number} 雪荷载 (N/m)
   */
  static snowLoad(
    snowDistributionCoefficient: number,
    snowPressure: number,
    openingReductionCoefficient: number,
    projectionAreaOfSectionsPipesWalkways: number,
    totalContourAreaOfCalculationDeck: number,

  ): number {
    // 防止除零错误
    if (totalContourAreaOfCalculationDeck === 0) {
      return 0;
    }
    
    // 计算积雪实际分布系数K = gamma * Ab / A1
    // gamma - 镂空折减系数
    // Ab - 型钢、管道及走道板在计算桥面的投影面积
    // A1 - 计算桥面轮廓总面积
    const K = (openingReductionCoefficient * projectionAreaOfSectionsPipesWalkways) / totalContourAreaOfCalculationDeck;
    
    // 雪荷载标准值计算公式：K * μr * S0
    // K - 积雪实际分布系数
    // μr - 积雪分布系数
    // S0 - 基本雪压
    const load = K * snowDistributionCoefficient * snowPressure * 1000; // 转换为N/m
    
    // 保留两位小数返回
    return parseFloat(load.toFixed(2));
  }

  /**
   * 检修荷载计算
   * 处理检修荷载标准值，确保返回格式统一
   * 
   * @param {number} maintenanceLoad 检修荷载标准值 (N/m)
   * @returns {number} 检修荷载 (N/m)
   */
  static maintenanceLoad(
    maintenanceLoad: number
  ): number {
    return parseFloat(maintenanceLoad.toFixed(2));
  }

  /**
   * 温度作用荷载计算
   * 根据管道特性和温度变化，计算温度应力引起的荷载
   * 基于材料的热膨胀和弹性模量进行计算
   * 
   * @param {number} pipeDiameter 管道外径 (m)
   * @param {number} pipeThickness 管道壁厚 (m)
   * @param {number} elasticModulus 弹性模量 (MPa)
   * @param {number} thermalExpansion 线膨胀系数 (1/°C)
   * @param {number} temperatureDifference 温度变化值 (°C)
   * @returns {number} 温度作用荷载 (N/m)
   */
  static temperatureLoad(
    pipeDiameter: number,
    pipeThickness: number,
    elasticModulus: number,
    thermalExpansion: number,
    temperatureDifference: number
  ): number {
    // 计算管道外半径
    const outerRadius = pipeDiameter / 2;
    
    // 计算管道内半径
    const innerRadius = outerRadius - pipeThickness;
    
    // 计算管道圆环截面积：π*(R²-r²)
    const crossSectionArea = Math.PI * (Math.pow(outerRadius, 2) - Math.pow(innerRadius, 2));
    
    // 计算温度应力：σ = E * α * ΔT
    // E - 弹性模量
    // α - 线膨胀系数
    // ΔT - 温度变化值
    const stress = elasticModulus * thermalExpansion * temperatureDifference;
    
    // 计算温度荷载：F = σ * A
    // A - 管道截面积
    const load = stress * crossSectionArea;
    
    // 保留两位小数返回
    return parseFloat(load.toFixed(2));
  }

  /**
   * 均布荷载组合计算
   * 根据设计规范，将各类荷载按恒载和活载分类，分别乘以相应的分项系数进行组合
   * 提供完整的荷载组合信息，用于结构设计计算
   * 
   * @param {number} pipeLoad 管道自重荷载 (N/m)
   * @param {number} mediumLoad 介质重量荷载 (N/m)
   * @param {number} insulationLoad 保温层重量荷载 (N/m)
   * @param {number} equipmentLoad 附属设备重量荷载 (N/m)
   * @param {number} windLoad 风荷载 (N/m)
   * @param {number} snowLoad 雪荷载 (N/m)
   * @param {number} maintenanceLoad 检修荷载 (N/m)
   * @param {number} temperatureLoad 温度作用荷载 (N/m)
   * @param {Object} loadFactors 荷载分项系数对象
   * @param {number} loadFactors.dead 恒载分项系数
   * @param {number} loadFactors.live 活载分项系数
   * @returns {Object} 荷载组合结果对象
   * @returns {number} return.totalLoad - 组合设计荷载(N/m)
   * @returns {number} return.deadLoad - 恒载组合值(N/m)
   * @returns {number} return.liveLoad - 活载组合值(N/m)
   * @returns {number} return.deadFactor - 使用的恒载分项系数
   * @returns {number} return.liveFactor - 使用的活载分项系数
   */
  static combinedLoad(
    pipeLoad: number,
    mediumLoad: number,
    insulationLoad: number,
    equipmentLoad: number,
    windLoad: number,
    snowLoad: number,
    maintenanceLoad: number,
    temperatureLoad: number,
    loadFactors: { dead: number; live: number }
  ): {
    totalLoad: number;
    deadLoad: number;
    liveLoad: number;
    deadFactor: number;
    liveFactor: number;
  } {
    // 参数检查和默认值处理，确保所有参数都有有效数值
    const safePipeLoad = pipeLoad || 0;
    const safeMediumLoad = mediumLoad || 0;
    const safeInsulationLoad = insulationLoad || 0;
    const safeEquipmentLoad = equipmentLoad || 0;
    const safeWindLoad = windLoad || 0;
    const safeSnowLoad = snowLoad || 0;
    const safeMaintenanceLoad = maintenanceLoad || 0;
    const safeTemperatureLoad = temperatureLoad || 0;
    const safeDeadFactor = (loadFactors && loadFactors.dead) || 1.2; // 默认恒载系数1.2
    const safeLiveFactor = (loadFactors && loadFactors.live) || 1.4; // 默认活载系数1.4

    // 恒载组合：管道自重 + 介质重量 + 保温层重量 + 附属设备重量 + 温度作用
    const deadLoad = safePipeLoad + safeMediumLoad + safeInsulationLoad + safeEquipmentLoad + safeTemperatureLoad;
    
    // 活载组合：风荷载 + 雪荷载 + 检修荷载
    const liveLoad = safeWindLoad + safeSnowLoad + safeMaintenanceLoad;
    
    // 根据跨越设计规范，恒载和活载分别采用不同的分项系数进行组合
    // 组合设计荷载 = 恒载 * 恒载分项系数 + 活载 * 活载分项系数
    const combinedLoadValue = deadLoad * safeDeadFactor + liveLoad * safeLiveFactor;
    
    // 返回完整的荷载组合信息，保留两位小数
    return {
      totalLoad: parseFloat(combinedLoadValue.toFixed(2)),
      deadLoad: parseFloat(deadLoad.toFixed(2)),
      liveLoad: parseFloat(liveLoad.toFixed(2)),
      deadFactor: safeDeadFactor,
      liveFactor: safeLiveFactor
    };
  }
}